using System;
using System.Collections.Generic; 
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
#endif 

namespace XFFSM
{

    /// <summary>
    /// 程序集工具
    /// </summary>
    public class AssemblyTools
    {

        private static Dictionary<string, Type> typeCaches = new Dictionary<string, Type>();

        /// <summary>
        /// 根据名称来获取类型
        /// </summary>
        /// <param name="classFullName">类名(含命名空间)</param>
        /// <returns></returns>
        internal static Type GetType(string classFullName)
        {
            if (string.IsNullOrEmpty(classFullName)) return null;

            if (typeCaches.ContainsKey(classFullName) && typeCaches[classFullName] != null) return typeCaches[classFullName];

            typeCaches.Remove(classFullName);

            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

            for (int i = 0; i < assemblies.Length; i++)
            {
                Assembly assembly = assemblies[i];

                Type type = assembly.GetType(classFullName);

                if (type != null) 
                {
                    typeCaches.Add(classFullName, type);
                    break;
                } 
            }
            
            if (typeCaches.ContainsKey(classFullName))
                return typeCaches[classFullName];

            return null;
        }
         
#if UNITY_EDITOR
         
        /// <summary>
        /// 获取所有状态脚本(仅编辑器有效)
        /// </summary>
        /// <returns></returns>
        public static List<MonoScript> GetAllStatesType()
        { 
            List<MonoScript> states = new List<MonoScript>();

            string[] scripts = AssetDatabase.FindAssets("t:Script");

            foreach (var item in scripts)
            {
                string path = AssetDatabase.GUIDToAssetPath(item);
                MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(path);

                if (script == null) continue;

                Type type = script.GetClass();

                if (type == null) continue;

                if(type.IsSubclassOf(typeof(FSMState)))
                    states.Add(script);
                //if (IsBaseByClass(type, typeof(FSMState)))
                //{
                //    states.Add(script);
                //}
            }

            return states;
        }

        /// <summary>
        /// 根据状态脚本全名称获取脚本guid(仅编辑器有效)
        /// </summary>
        /// <returns></returns>
        public static string GetGUIDByStateClassFullName(string fullName)
        {
            List<MonoScript> scripts = GetAllStatesType();

            foreach (var item in scripts)
            {
                if (item.GetClass() != null && item.GetClass().FullName.Equals(fullName))
                {
                    return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(item));
                }
            }

            return string.Empty;
        }

#endif

    }

}

